﻿
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Serilog;
using System;
using System.IO;
using System.Management;
using System.Net;
using System.Net.NetworkInformation;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;

namespace ybx_caller.service
{
    public class CallYhYB
    {
        private static string file_name = null;

        [DllImport("kernel32")]
        private static extern int GetPrivateProfileString(string section, string key, string def, byte[] retVal, int size, string filePath);

        /// <summary>
        /// 医保调用核心
        /// </summary>
        /// <param name="astr_jyhb">交易编号</param>
        /// <param name="astr_jysr">交易输入</param>
        /// <returns></returns>
        private static String yh_hb_call(string astr_jyhb, string astr_jysr)
        {
            System.Type yh = Type.GetTypeFromProgID("yinhai.yh_hb_sctr");
            Object yhObject = null;
            string astr_jysc = String.Empty;
            try
            {
                yhObject = System.Activator.CreateInstance(yh);
                object[] args = new object[] { astr_jyhb, astr_jysr, astr_jysc };
                ParameterModifier pm = new ParameterModifier(3);
                pm[0] = false;
                pm[1] = false;
                pm[2] = true;
                ParameterModifier[] pmd = { pm };
                yh.InvokeMember("yh_hb_call", BindingFlags.InvokeMethod, null, yhObject, args, pmd, System.Globalization.CultureInfo.CurrentCulture, null);
                astr_jysc = args[2].ToString();
            }
            catch (Exception ex)
            {
                astr_jysc = "";
                Console.WriteLine(ex.Message);
                //astr_jysc = "交易调用出错" + ex.Message;
            }
            yh = null;
            yhObject = null;
            return astr_jysc;
        }

        /// <summary>
        ///  构造入参
        /// </summary>
        private static string BuildInJson(String infno, String mdtrtarea_admvs1, String insuplc_admdvs1, String opter1, String opter_name1, String sign_no1, String data)
        {
            #region 入参初始化
            file_name = Directory.GetCurrentDirectory() + "\\ybx.ini";
            string time = string.Format("{0:yyyyMMddHHmmss}", DateTime.Now);

            Random random = new Random();
            int randomNumber = random.Next(1000, 10000);
            string round = randomNumber.ToString();

            string inf_time = string.Format("{0:yyyy-MM-dd HH:mm:ss}", DateTime.Now);
            string fixmedins_code = INIRead("xyb", "fixmedins_code", file_name);
            string fixmedins_name = INIRead("xyb", "fixmedins_name", file_name);
            string msgid = fixmedins_code + time + round;
            string dev_no = INIRead("xyb", "dev_no", file_name);
            string dev_safe_info = INIRead("xyb", "dev_safe_info", file_name);
            string cainfo = INIRead("xyb", "cainfo", file_name);
            string signtype = INIRead("xyb", "signtype", file_name);
            string infver = INIRead("xyb", "infver", file_name);
            string opter_type = INIRead("xyb", "opter_type", file_name);
            string recer_sys_code = INIRead("xyb", "recer_sys_code", file_name);
            string opter = INIRead("xyb", "opter", file_name);
            string opter_name = INIRead("xyb", "opter_name", file_name);
            string mdtrtarea_admvs = INIRead("xyb", "mdtrtarea_admvs", file_name);
            string insuplc_admdvs = INIRead("xyb", "insuplc_admdvs", file_name);
            string sign_no = INIRead("xyb", "sign_no", file_name);
            if ((!"".Equals(mdtrtarea_admvs1)) && (mdtrtarea_admvs1 != null))
            {
                mdtrtarea_admvs = mdtrtarea_admvs1;
            }
            if ((!"".Equals(insuplc_admdvs1)) && (insuplc_admdvs1 != null))
            {
                insuplc_admdvs = insuplc_admdvs1;
            }
            if ((!"".Equals(opter1)) && (opter1 != null))
            {
                opter = opter1;
            }
            if ((!"".Equals(opter_name1)) && (opter_name1 != null))
            {
                opter_name = opter_name1;
            }
            if ((!"".Equals(sign_no1)) && (sign_no1 != null))
            {
                sign_no = sign_no1;
            }
            #endregion

            #region 拼接入参
            StringBuilder sb = new StringBuilder();
            sb.Append("{");
            // 交易编号
            sb.Append("\"infno\":"); sb.Append("\""); sb.Append(infno); sb.Append("\""); sb.Append(",");
            // 发送方报文ID
            sb.Append("\"msgid\":"); sb.Append("\""); sb.Append(msgid); sb.Append("\""); sb.Append(",");
            // 就医地医保区划
            sb.Append("\"mdtrtarea_admvs\":"); sb.Append("\""); sb.Append(mdtrtarea_admvs); sb.Append("\""); sb.Append(",");
            // 参保地医保区划
            sb.Append("\"insuplc_admdvs\":"); sb.Append("\""); sb.Append(insuplc_admdvs); sb.Append("\""); sb.Append(",");
            // 接收方系统代码
            sb.Append("\"recer_sys_code\":"); sb.Append("\""); sb.Append(recer_sys_code); sb.Append("\""); sb.Append(",");
            // 设备编号 
            sb.Append("\"dev_no\":"); sb.Append("\""); sb.Append(dev_no); sb.Append("\""); sb.Append(",");
            // 设备安全信息
            sb.Append("\"dev_safe_info\":"); sb.Append("\""); sb.Append(dev_safe_info); sb.Append("\""); sb.Append(",");
            // 数字签名信息
            sb.Append("\"cainfo\":"); sb.Append("\""); sb.Append(cainfo); sb.Append("\""); sb.Append(",");
            // 签名类型
            sb.Append("\"signtype\":"); sb.Append("\""); sb.Append(signtype); sb.Append("\""); sb.Append(",");
            // 接口版本号
            sb.Append("\"infver\":"); sb.Append("\""); sb.Append(infver); sb.Append("\""); sb.Append(",");
            // 经办人类别
            sb.Append("\"opter_type\":"); sb.Append("\""); sb.Append(opter_type); sb.Append("\""); sb.Append(",");
            // 经办人
            sb.Append("\"opter\":"); sb.Append("\""); sb.Append(opter); sb.Append("\""); sb.Append(",");
            // 经办人姓名
            sb.Append("\"opter_name\":"); sb.Append("\""); sb.Append(opter_name); sb.Append("\""); sb.Append(",");
            // 交易时间
            sb.Append("\"inf_time\":"); sb.Append("\""); sb.Append(inf_time); sb.Append("\""); sb.Append(",");
            // 定点医药机构编号
            sb.Append("\"fixmedins_code\":"); sb.Append("\""); sb.Append(fixmedins_code); sb.Append("\""); sb.Append(",");
            // 定点医药机构名称
            sb.Append("\"fixmedins_name\":"); sb.Append("\""); sb.Append(fixmedins_name); sb.Append("\""); sb.Append(",");
            // 交易签到流水号
            sb.Append("\"sign_no\":"); sb.Append("\""); sb.Append(sign_no); sb.Append("\""); sb.Append(",");
            // 交易输入
            sb.Append("\"input\":");
            sb.Append(data);
            sb.Append("}");
            #endregion

            return sb.ToString();
        }

        /// <summary>
        /// 读取配置文件
        /// </summary>
        private static string INIRead(string section, string key, string path)
        {
            try
            {
                byte[] Buffer = new byte[1024];
                int bufLen = GetPrivateProfileString(section, key, "", Buffer, Buffer.GetUpperBound(0), path);
                string s = Encoding.UTF8.GetString(Buffer, 0, bufLen);
                return s;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                return string.Empty;
            }
        }

        /// <summary>
        ///  获取签到号
        /// </summary>
        /// <param name="infno"></param>
        /// <param name="opter1"></param>
        /// <param name="opter_name1"></param>
        /// <returns></returns>
        public static String getSignNo(String opter1, String opter_name1,String insuplc,String medplc)
        {
            String sign_no = "";
            String ip = getIp();
            String mac = getMac();          
            var signIn = new
            {
                ip = ip,
                mac = mac,
                opter_no = opter1
            };

            string t9001in = JsonConvert.SerializeObject(new { signIn });

          

            //String t9001in = JsonSerializer.Serialize(new { signIn = signIn });
            String input_msg = BuildInJson("9001", medplc, insuplc, opter1, opter_name1, "", t9001in);
            Log.Information("【9001】输入: " + input_msg);
            String output_msg = yh_hb_call("9001", input_msg);
            Log.Information("【9001】输出: " + output_msg);
            try
            {
                JObject jsonObj = JObject.Parse(output_msg);
                sign_no = jsonObj["output"]["signinoutb"]["sign_no"].ToString();
            }
            catch (Exception ex) {
                Console.WriteLine(ex.Message);         
            }

            return sign_no;
        }

        /// <summary>
        /// 获取ip
        /// </summary>
        public static string getIp()
        {
            string ip = "";
            string hostInfo = Dns.GetHostName();
            System.Net.IPAddress[] addressList = Dns.GetHostEntry(Dns.GetHostName()).AddressList;
            for (int i = 0; i < addressList.Length; i++)
            {
                ip = addressList[i].ToString();
            }
            return ip;
        }

        /// <summary>
        /// 获取mac
        /// </summary>
        /// <returns></returns>
        private static String getMac()
        {
            string mac = "";
            ManagementClass mc = new ManagementClass("Win32_NetworkAdapterConfiguration");
            ManagementObjectCollection moc = mc.GetInstances();
            foreach (ManagementObject mo in moc)
            {
                if (mo["IPEnabled"].ToString() == "True")
                {
                    mac = mo["MacAddress"].ToString();
                }
            }
            return mac;
        }

        public static String getYbBack(String infno, String mdtrtarea_admvs1, String insuplc_admdvs1, String opter1, String opter_name1, String data)
        {
            String sign_no = getSignNo("00000", "全院","420300","420300");
            String input_msg = BuildInJson(infno, mdtrtarea_admvs1, insuplc_admdvs1, opter1, opter_name1, sign_no, data);
            String output_msg = yh_hb_call(infno, input_msg);
            return output_msg;
        }

    }
}
